package com.wocao.controller;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wocao.entity.*;
import com.wocao.excelListener.SysUserReadListener;
import com.wocao.entity.ResponseResult;
import com.wocao.entity.SysMenu;
import com.wocao.entity.SysUser;
import com.wocao.service.SysUserService;
import com.wocao.utils.ExcelUtil;
import com.wocao.utils.TreeUtilsByUsername;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;

/**
 * 用户信息表 前端控制器
 */
@CrossOrigin
@RestController
@RequestMapping("sysUser")
@CacheConfig(cacheNames = "sysUser")
public class SysUserController {

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Autowired
    private SysUserService sysUserService;

    //分页用户+搜索
    @PostMapping("/user/{current}")
    public ResponseResult allPage(@PathVariable int current, @RequestBody ReqBody reqBody) {
        try {
            Page<SysUser> sysUserPage = sysUserService.allPage(new Page<>(current, reqBody.getSize()), reqBody);
            return ResponseResult.ok(sysUserPage);
        } catch (Exception e) {
            return ResponseResult.error(500L, "服务器内部错误");
        }
    }

    //添加用户
    @PostMapping("user")
    @CachePut(key = "T(String).valueOf(#sysUser.userId)")
    public ResponseResult add(@RequestBody SysUser sysUser) {
        try {
            sysUserService.addUser(sysUser);
            return ResponseResult.ok(sysUser);
        } catch (Exception e) {
            return ResponseResult.error(500L);
        }
    }

    //修改用户
    @PutMapping("user")
    @CachePut(key = "T(String).valueOf(#sysUser.userId)")
    public ResponseResult update(@RequestBody SysUser sysUser) {
        try {
            sysUserService.updateUser(sysUser);
            return ResponseResult.ok(sysUser);
        } catch (Exception e) {
            return ResponseResult.error(500L);
        }
    }

    //批量删除
    @DeleteMapping("user")
    public ResponseResult delete(@RequestBody ReqBody reqBody) {
        try {
            sysUserService.batchRemoveUser(reqBody.getUserIds());
            return ResponseResult.ok();
        } catch (Exception ex) {
            return ResponseResult.error(500L, "");
        }
    }


    //重置用户
    @PutMapping("userpwd")
    public ResponseResult password(@RequestBody SysUser sysUser) {
        try {
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
            LocalDateTime upTime = LocalDateTime.now();
            sysUser.setUpdateTime(upTime);
            sysUserService.updateById(sysUser);
            return ResponseResult.ok();
        } catch (Exception e) {
            return ResponseResult.error(500L);
        }
    }

    /**
     * 导入
     */
    @PostMapping("/import")
    public void port(MultipartFile userEx) throws Exception {
        SysUserReadListener listener = new SysUserReadListener(sysUserService);
        EasyExcel.read(userEx.getInputStream(), SysUser.class, listener).sheet().doRead();
    }


    /**
     * 导出
     */
    @GetMapping("export")
    public void export(String strIds, HttpServletResponse response) throws IOException {
        List<SysUser> userList;
        String[] userIds = strIds.split(",");
        //导出所有
        if (userIds.length == 0 || "".equals(strIds)) {
            userList = sysUserService.list();
        }
        //导出选择的id
        else {
            userList = sysUserService.listByIds(Arrays.asList(userIds));
        }
        ExcelUtil.export(response, SysUser.class, userList);
    }

    @GetMapping("/sysUser-sysMenus/{username}")
    public ResponseResult<List<SysMenu>> findSysMenusByUsername(@PathVariable String username) {
        try {List<SysMenu> sysMenus = sysUserService.getSysMenusWithChildrenByUsername(username);
        List<SysMenu> sysMenusTree = TreeUtilsByUsername.menusToTree(sysMenus);
        return ResponseResult.ok(sysMenusTree);} catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(500l, "查询失败" + e.getMessage());
        }

    }

    @GetMapping("/personalInformation/{username}")
    public ResponseResult<List<SysMenu>> findPersonalInformationByUsername(@PathVariable String username) {
        try {
            SysUser personalInformation = sysUserService.getPersonalInformationByUsername(username);
            return ResponseResult.ok(personalInformation);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(500l, "查询失败" + e.getMessage());
        }

    }

    @PutMapping("/updatePersonalInformation/")
    public ResponseResult<List<SysMenu>> updatePersonalInformation(@RequestBody SysUser sysUser) {
        try {
            sysUserService.updateById(sysUser);
            return ResponseResult.ok(sysUser);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(500l, "修改失败" + e.getMessage());
        }

    }

    @PutMapping("/updatePassword/")
    public ResponseResult<List<SysMenu>> updatePassword(@RequestBody SysUser sysUser,
                                                        @RequestParam String oldPassword,
                                                        @RequestParam String newPassword) {
        try {
            if (oldPassword.equals(newPassword)){
                return ResponseResult.error(400l,"新密码不能与旧密码相同");
            }
            SysUser sysUserById = sysUserService.getById(sysUser.getUserId());
            String oldEncodePassword = sysUserById.getPassword();
            boolean matches = bCryptPasswordEncoder.matches(oldPassword,oldEncodePassword);
            if (!matches){
                return ResponseResult.error(400l,"旧密码错误");
            }
            sysUser.setPassword(bCryptPasswordEncoder.encode(sysUser.getPassword()));
            sysUserService.updateById(sysUser);
            return ResponseResult.ok(sysUser);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseResult.error(500l, "验证密码失败" + e.getMessage());
        }
    }
}
